<script setup>
// vue API
import { ref, shallowRef } from "vue";

// ol API
import { Vector as VectorLayer } from "ol/layer";
import VectorSource from "ol/source/Vector";
import { Feature } from "ol";
import { Point, Polygon } from "ol/geom";
import { Circle as CircleStyle, Fill, Stroke, Style } from "ol/style";

// ol Custom API
import {
  getOverlayByGroupId,
  clearOverlay,
} from "@/utils/ol/overlay/helper.js";
import Tooltip from "@/utils/ol/overlay/Tooltip";
import Popup from "@/utils/ol/overlay/Popup";
import { randomPosition } from "@/utils/random";
import { layoutOptimized2 as overlayLayoutOptimized } from "@/utils/ol/overlay/layoutOptimized";

// ol Composables
import useInitMap from "@/utils/ol/useInitMap";
import useDrawPoint from "@/utils/ol/draw/useDrawPoint";

// 工具函数
import { random } from "lodash-es";
import store from "@/utils/store";

const { map } = useInitMap({
  target: "mapContainer",
  // zoom: 9,
  attributionInfo: "碰撞检测学习（版权属于Carlos）",
  onLoadEnd: onLoadEnd,
});

const pointSource = shallowRef(null);
const pointLayer = shallowRef(null);
const tooltipIndex = ref(0);

function drawPopup() {
  const position = [113.28303915556452, 23.65937959757133];

  const feature = new Feature(new Point(position));

  feature.setStyle(
    new Style({
      image: new CircleStyle({
        radius: 5,
        fill: new Fill({ color: "red" }),
        stroke: new Stroke({ color: "black", width: 1 }),
      }),
    })
  );

  pointSource.value.addFeature(feature);

  const popup = new Popup({
    element: `
      <div style="width: 200px; height: 50px; text-align:center; line-height:50px; font-size:22px; font-weight:bold; color:red">
        ${`Popup${tooltipIndex.value}`}
        </div>
      `,
    position: position,
    placement: tooltipDirection.value,
    groupId: "popup-test",
    id: `popup-${tooltipIndex.value}`,
    visibility: true,
    minZoom: 11,
    maxZoom: 13,
    target: position,
    trigger: "click",
  });

  window.map.addOverlay(popup);

  tooltipIndex.value++;
}

// 在地图上绘制Tooltip
function drawTooltip() {
  let removeDraw;
  const { remove } = useDrawPoint(map.value, pointSource.value, e => {
    const position = e.feature.getGeometry().getCoordinates();
    addTooltip(position);
  });

  removeDraw = remove;

  window.addEventListener(
    "keydown",
    event => {
      if (event.key === "Escape" && removeDraw) {
        removeDraw();
        removeDraw = null;
      }
    },
    false
  );
}

// 添加Tooltip
function addTooltip(position, zIndex) {
  console.log(position);

  tooltipIndex.value++;

  const tooltip = new Tooltip({
    element: `
      <div style="width: 200px; height: 50px; text-align:center; line-height:50px; font-size:22px; font-weight:bold; color:red">
        ${`Tooltip${tooltipIndex.value}`}
        </div>
      `,
    position: position,
    placement: tooltipDirection.value,
    groupId: "tooltip-test",
    id: `tooltip-${tooltipIndex.value}`,
    visibility: true,
    zIndex: zIndex,
    minZoom: 11,
    maxZoom: 13,
  });

  window.map.addOverlay(tooltip);
}

// 保存Tooltip
function saveTooltip() {
  const tooltips = getOverlayByGroupId(window.map, "tooltip-test");

  store.set(
    "tooltips",
    tooltips.map(tooltip => {
      return {
        id: tooltip.getId(),
        position: tooltip.getPosition(),
      };
    })
  );
}

// 切换Tooltip可见性
function toggleTooltip() {
  const tooltips = getOverlayByGroupId(window.map, "tooltip-test");

  const visibility = tooltips[0].getVisibility();

  tooltips.forEach(tooltip => {
    tooltip.setVisibility(!visibility);
  });
}

// 清空所有Tooltip
function clearTooltip() {
  clearOverlay(window.map);

  pointSource.value.clear();

  tooltipIndex.value = 0;
}

// 随机生成Tooltip
function randomGenerateTooltip() {
  clearTooltip();
  const extent = [
    112.94307394560359, 23.56818375754002, 113.42303915556452,
    23.75057643760265,
  ];

  const positions = randomPosition(window.map, 20, extent);
  positions.forEach(position => {
    addTooltip(position);
    pointSource.value.addFeature(new Feature(new Point(position)));
  });
}

// 布局优化
function layoutOptimization() {
  const tooltips = getOverlayByGroupId(window.map, "tooltip-test");

  overlayLayoutOptimized(tooltips);
}

const tooltipDirection = ref("top");

function changeTooltipDirection() {
  const tooltips = getOverlayByGroupId(window.map, "tooltip-test");

  tooltips.forEach(tooltip => {
    tooltip.setPlacement(tooltipDirection.value);
  });
}

function onLoadEnd(map) {
  pointSource.value = new VectorSource();
  pointLayer.value = new VectorLayer({
    source: pointSource.value,
    style: {
      "circle-fill-color": "red", // 圆形颜色
      "circle-radius": 5, // 圆形半径
      "circle-stroke-color": "black", // 圆形边框颜色
      "circle-stroke-width": 1, // 圆形边框宽度
    },
  });
  map.addLayer(pointLayer.value);

  const tooltips = store.get("tooltips");
  tooltips.forEach((tooltip, index) => {
    addTooltip(tooltip.position, index);
    pointSource.value.addFeature(new Feature(new Point(tooltip.position)));

    tooltipIndex.value++;
  });
}
</script>

<template>
  <activity-panel width="fit-content">
    <div class="buttons">
      <el-button @click="drawPopup">绘制Popup</el-button>
      <el-button @click="drawTooltip">绘制Tooltip</el-button>
      <el-button @click="saveTooltip">保存Tooltip</el-button>
      <el-button @click="toggleTooltip">切换Tooltip可见性</el-button>
      <el-button @click="clearTooltip">清空Tooltip</el-button>
      <el-button @click="randomGenerateTooltip">随机生成Tooltip</el-button>
      <el-button @click="collisionDetection">碰撞检测</el-button>
      <el-button @click="layoutOptimization">布局优化</el-button>
    </div>

    <div
      class="buttons2"
      style="margin-top: 10px"
      @change="changeTooltipDirection">
      <el-radio-group v-model="tooltipDirection" size="small">
        <el-radio-button label="上" value="top" />
        <el-radio-button label="下" value="bottom" />
        <el-radio-button label="左" value="left" />
        <el-radio-button label="右" value="right" />
      </el-radio-group>
    </div>
  </activity-panel>

  <div id="mapContainer" style="width: 100vw; height: 100vh"></div>
</template>

<style scoped lang="scss">
.buttons {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
}
</style>
